import xmltodict

from untils.log_ import logger


def response_to_json(response):
    """
    多协议封装
    :param response:
    :return:json
    """
    res_txt = response.text
    if res_txt.startswith('<?xml'):
        final_txt = xmltodict.parse(res_txt)
    elif res_txt.startswith('<!doctype html>'):
        final_txt = xmltodict.parse(res_txt)
    else:
        final_txt = response.json()
    return final_txt


def common_assert(response, expect: dict):
    """
    通用断言函数
    :param expect:
    :param response:

    :return:
    """
    # assert response.status_code == expect['status_code']
    # result_json = response_to_json(response)
    result_json = response
    result_key = list(get_keys(result_json))

    expect_key = list(get_keys(expect))
    # is_in_list(result_key, expect_key)
    for key in expect_key:
        v_e = get_value_by_key(expect, key)
        v_r = get_value_by_key(result_json, key)
        logger.info(f"预期：{key}:{v_e}\t实际：{key}:{v_r}")
        if isinstance(v_r, str):
            assert v_e in v_r, f"预期：{key}:{v_e}\t实际：{key}:{v_r}"
        else:
            assert v_e == v_r, f"预期：{key}:{v_e}\t实际：{key}:{v_r}"


def is_same(template: list, src: list):
    """
    判断两个列表是否相同
    :param template:
    :param src:
    :return:
    """
    index = len(template)
    for i in range(index):
        if template[i] not in src:
            logger.error(f"参数\t{template[i]}\t错误")
            return False
    logger.info("参数格式正确")
    return True


def is_in_list(result: list, expect: list):
    """
    判断一个列表是否在另一个列表中
    :param result:
    :param expect:
    :return:
    """
    for i in expect:
        if i in result:
            ...
        else:
            raise Exception(f"参数\t{i}\t错误")


def get_keys(value):
    """
    获取字典中中所有key的递归函数
    :param value:
    :return:
    """
    if isinstance(value, dict):
        for key, nested_value in value.items():
            yield key
            yield from get_keys(nested_value)


def get_value_by_key(dict1: dict, key):
    """
    通过key获取value
    :param dict1:
    :param key:
    :return:
    """
    for k, v in dict1.items():
        if k == key:
            return v
        elif isinstance(v, dict):
            return get_value_by_key(v, key)

    return None


if __name__ == '__main__':
    input_data = {"method": "post", "url": "/api/sys/user", "json": {"mobile": {"id": "155365161664"}}}
    expect_data = {"method": "post", "url": "/api/sys/user", "json": {"mobile": {"id": "15565161664"}}}
    common_assert(input_data, expect_data)
